package eop.project

import java.text.SimpleDateFormat;
import java.util.Map;

class LoadVolcanoDatabase {
	
	void readAndSaveVolcanoDatabase(volcanoXmlService){
		Map volcanoList = readVolcanoDataFromWeb(volcanoXmlService);
		saveVolcano(volcanoList);
	}
	
	Map readVolcanoDataFromWeb(volcanoXmlService) {
		def txt = volcanoXmlService.html2Xml()
		def parser = new org.cyberneko.html.parsers.SAXParser()
		parser.setFeature('http://xml.org/sax/features/namespaces', false)
		def page = new XmlSlurper(parser).parseText(txt)
		
		def allVolcanos = [:]
		def volcano = [:]
		
		int tdCounter = 0
		int volcanoCounter = 0
		int itemCounter = 0
		boolean volcanoData = false
		
		def tds = page.depthFirst().findAll {
			it != null && it.name() == 'TD'
		};
		
		tds.each{
			
			if (tdCounter > 36){
				volcanoData = true
			}
			
			if(volcanoData){
				volcano["$itemCounter"] = it.toString()
				allVolcanos["$volcanoCounter"] = volcano
				itemCounter++
			}
			
			if(itemCounter > 22){
				volcanoCounter++
				itemCounter=0
				volcano = [:]
			}
			
			//println "TD $tdCounter" + it
			String a = it.toString()
			//println "str: $a"
			tdCounter++
		}
		
		return allVolcanos;
	}
	
	void saveVolcano(Map volList){
		/*
		 0 Year
		 1 Mo
		 2 Dy
		 3 Tsu
		 4 EQ
		 5 AddlVolInfo
		 6 Name
		 7 Location
		 8 Latitude
		 9 Longitude
		 10 Elevation
		 11 Type
		 12 VEI
		 13 Agent
		 14 Num
		 15 De
		 16 Num
		 17 De
		 18 $Mill
		 19 De
		 20 Num
		 21 De
		 22 Photos
		 */
		Volcano v;
		Location location;
		volList.each{ k,volcanoMap ->
			
			v = Volcano.findByVolcanoName(volcanoMap["6"].toUpperCase());
			location = Location.findByLocationName(volcanoMap["7"]);
			
			if(!location){
				location = new Location(locationName:volcanoMap["7"],lattitude:volcanoMap["8"],longitude:volcanoMap["9"],elevation:volcanoMap["10"]);
				
				location.validate()
				if(location.hasErrors()){
					location.errors.each{ println "Error : $it" }
				}
				location.save(flush:true)
				println "location saved: " + location.locationName
			}
			else
				println "location found: " + location.locationName
			
			
			if(!v){
				v = new Volcano(volcanoName: volcanoMap["6"].toUpperCase(),volcanoType:volcanoMap["11"],status:volcanoMap["5"]);
				v.location = location
				
				v.validate()
				if(v.hasErrors()){
					v.errors.each{ println "Error : $it" }
				}
				v.save(flush:true)
				println "Volcano saved: " + v.volcanoName
			}
			else
				println "Volcano found: " + v.volcanoName
			
			
			Damage damage = getDamageObject(volcanoMap);
			damage.validate()
			if(damage.hasErrors()){
				damage.errors.each{ println "Error : $it" }
			}
			damage.save(flush:true)
			//println "Damages are saved: " + damage.damages
			
			SimpleDateFormat fmt = new SimpleDateFormat("dd/MM/yyyy");
			volcanoMap["1"]  = (volcanoMap["1"] == null || volcanoMap["1"].length() <=0) ? "1":volcanoMap["1"]
			volcanoMap["2"]  = (volcanoMap["2"] == null|| volcanoMap["2"].length() <=0) ? "1":volcanoMap["2"]
			
			Date event = fmt.parse(volcanoMap["2"]+"/"+volcanoMap["1"]+"/"+volcanoMap["0"])
			
			Eruption  erruption = Eruption.findByEventDate(event)
			if(!erruption){
				erruption = new Eruption(vei:volcanoMap["12"],agent:volcanoMap["13"],eventDate:event);
				
				erruption.damage = damage
				erruption.volcano = v
				
				erruption.validate()
				if(erruption.hasErrors()){
					erruption.errors.each{ println "Error : $it" }
				}				
				erruption.save(flush:true)
			}
			v.addToEruptions(erruption).save()
		}
	}
	
	Damage getDamageObject(Map volList){
		int injuries = (volList["16"] != null && volList["16"].length() > 0) ? Integer.parseInt(volList["16"]): 0
		int houses = (volList["20"] != null && volList["20"].length() > 0) ? Integer.parseInt(volList["20"]) : 0
		float damages = (volList["18"] != null && volList["18"].length() > 0) ? Float.parseFloat(volList["18"]) : 0
		int deaths = (volList["14"] != null && volList["14"].length() > 0) ? Integer.parseInt(volList["14"]) : 0
		new Damage(injuries:injuries,Houses:houses,numberOfDeaths: deaths,damages:damages);
	}
}
